#pragma once
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <cstring>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#define ForRead 1
#define ForWrite 2

enum
{
    OK = 0,
    BUILD_FAIL,
    DELETE_FAIL,
    OPEN_FAIL
};

const std::string gcommfile = "./fifo";
class Fifo
{
public:
    Fifo(const std::string commfile = gcommfile) : _commfile(commfile), _mode(0666), _fd(-1)
    {
    }
    // 创建命名管道
    void Build()
    {
        int n = mkfifo(_commfile.c_str(), _mode);
        if (n < 0)
        {
            std::cerr << "Build fail" << strerror(errno) << errno << std::endl;
            exit(BUILD_FAIL);
        }
        std::cout << "Bulid success" << std::endl;
    }

    // 打开管道
    void Open(int mode)
    {
        if (mode == ForRead)
            _fd = open(_commfile.c_str(), O_RDONLY);
        else if (mode == ForWrite)
            _fd = open(_commfile.c_str(), O_WRONLY);
        else
        {
        }
        if (_fd < 0)
        {
            std::cerr << "open error: " << strerror(errno) << " errno: " << errno << std::endl;
            exit(OPEN_FAIL);
        }
    }
    // 向文件内写数据
    void Send(const std::string &msgin)
    {
        ssize_t n = write(_fd, msgin.c_str(), msgin.size());
        (void)n;
    }
    int Read(std::string *msgout)
    {
        char buffer[128] = {0};
        ssize_t n = read(_fd, buffer, sizeof(buffer) - 1);
        if (n > 0)
        {
            buffer[n] = 0;
            *msgout = buffer;
            return n;
        }
        else if (n == 0)
        {
            return 0;
        }
        else
        {
            return -1;
        }
    }
    // 删除管道
    void Delete()
    {
        int n = unlink(_commfile.c_str());
        if (n < 0)
        {
            perror("unlink fail");
            exit(DELETE_FAIL);
        }
        (void)n;
        std::cout << "Delete success" << std::endl;
    }
    ~Fifo()
    {
    }

private:
    std::string _commfile;
    mode_t _mode;
    int _fd;
};